<template>
  <view class="follow-container">
    <view class="nav">
      <text class="title">我的关注</text>
    </view>

    <view class="toolbar">
      <input class="search" type="text" v-model.trim="keyword" placeholder="搜索医生姓名/医院" @input="onSearchInput" />
    </view>

    <view v-if="loading" class="loading">加载中...</view>
    <view v-else>
      <view v-if="filteredTotal === 0" class="empty">暂无关注</view>
      <view v-else class="list">
        <view class="item" v-for="(row, idx) in pagedList" :key="row._key || idx">
          <image class="avatar" :src="row.avatar || defaultAvatar" mode="aspectFill" @tap="goDoctorDetail(row.doctorId)" />
          <view class="info" @tap="goDoctorDetail(row.doctorId)">
            <view class="line1">
              <text class="name">{{ row.name || ('医生' + row.doctorId) }}</text>
              <text class="title-badge" v-if="row.title">{{ row.title }}</text>
            </view>
            <view class="line2" v-if="row.hospital">{{ row.hospital }}</view>
            <view class="time">关注时间：{{ formatTime(row.followTime) }}</view>
          </view>
          <view class="ops">
            <button class="btn-cancel" size="mini" @tap.stop.prevent="onCancelById(row.doctorId || row.id, idx)" aria-label="取消关注">取消关注</button>
          </view>
        </view>

        <view class="load-more" v-if="!finished && filteredTotal > pageSize">
          <button class="btn-more" size="mini" :loading="loadingMore" @click="loadMore">加载更多</button>
        </view>
        <view class="no-more" v-else-if="finished">没有更多了</view>
      </view>
    </view>
  </view>
</template>

<script>
import { listMyFollow, cancelFollow } from '@/api/follow'
import { getDoctorDetail } from '@/api/doctor'

export default {
  data() {
    return {
      loading: false,
      loadingMore: false,
      rawList: [], // 原始关注记录
      rows: [],    // 合并了医生详情后的行数据
      page: 1,
      pageSize: 10,
      finished: false,
      keyword: '',
      doctorCache: {},
      defaultAvatar: '/static/images/profile.jpg',
      _cancelBusy: false
    }
  },
  computed: {
    filteredRows() {
      const kw = (this.keyword || '').toLowerCase()
      if (!kw) return this.rows
      return this.rows.filter(r => {
        const name = (r.name || '').toLowerCase()
        const hospital = (r.hospital || '').toLowerCase()
        return name.includes(kw) || hospital.includes(kw)
      })
    },
    filteredTotal() {
      return this.filteredRows.length
    },
    pagedList() {
      const end = this.page * this.pageSize
      return this.filteredRows.slice(0, end)
    }
  },
  onLoad() {
    this.fetch()
    // 监听来自医生详情页的关注状态变化
    this._followChangedHandler = (payload) => {
      try {
        if (!payload || !payload.doctorId) return
        const id = Number(payload.doctorId)
        if (payload.followed) {
          // 如果本地不存在，则新增并尝试补全详情
          const exists = this.rows.some(r => Number(r.doctorId) === id)
          if (!exists) {
            const rec = { _key: 'new-'+id, id: 'new-'+id, doctorId: id, followTime: Date.now() }
            this.rawList.unshift(rec)
            // 立即补全详情
            this.mergeDoctorDetails()
          }
        } else {
          // 取消关注：本地移除
          this.rawList = this.rawList.filter(r => Number(r.doctorId) !== id)
          this.rows = this.rows.filter(r => Number(r.doctorId) !== id)
        }
        // 重置分页以反映变更
        this.page = 1
        this.finished = this.pagedList.length >= this.filteredTotal
      } catch (e) { console.warn('follow-changed 处理失败', e) }
    }
    uni.$on && uni.$on('follow-changed', this._followChangedHandler)
  },
  onPullDownRefresh() {
    this.fetch()
  },
  onReachBottom() {
    this.loadMore()
  },
  onUnload() {
    // 解绑事件监听
    this._followChangedHandler && uni.$off && uni.$off('follow-changed', this._followChangedHandler)
    this._followChangedHandler = null
  },
  methods: {
    async fetch() {
      try {
        this.loading = true
        this.finished = false
        this.page = 1
        const res = await listMyFollow()
        const list = Array.isArray(res?.data) ? res.data : (Array.isArray(res) ? res : [])
        // 统一 doctorId / followTime 字段并强制转为数字ID
        this.rawList = list.map((it, idx) => {
          let did = it?.doctorId ?? it?.doctor_id ?? it?.docId ?? it?.doctorID ?? it?.doc_id
          if (did !== undefined && did !== null) {
            try { did = Number(String(did).trim()) } catch (_) { did = Number(did) }
          }
          const ft = it?.followTime || it?.createTime || it?.time || it?.addTime
          return {
            _key: it?.id || ('f-'+idx),
            id: it?.id || idx,
            doctorId: did,
            followTime: ft
          }
        }).filter(it => typeof it.doctorId === 'number' && !isNaN(it.doctorId) && it.doctorId > 0)
        try { console.log('[Follow] fetch mapped rawList size=', this.rawList.length, this.rawList.slice(0,3)) } catch (_) {}
        await this.mergeDoctorDetails()
      } catch (e) {
        console.error('加载关注列表失败', e)
        uni.showToast({ title: '加载失败', icon: 'none' })
      } finally {
        this.loading = false
        uni.stopPullDownRefresh && uni.stopPullDownRefresh()
      }
    },
    async mergeDoctorDetails() {
      // 并发加载医生详情并缓存
      const tasks = this.rawList.map(async (rec) => {
        const id = Number(rec.doctorId)
        if (!id) return null
        const cached = this.doctorCache[id]
        if (cached) return { ...rec, ...cached }
        try {
          const res = await getDoctorDetail(id)
          const d = res && (res.data || res) || {}
          const row = {
            doctorId: id,
            name: d.doctorName || d.name || d.realName || '医生',
            title: d.roleName || d.title || d.jobTitle || '医师',
            hospital: d.hospitalName || d.hospital || '',
            avatar: d.doctorImage || d.avatar || d.headImg || d.avatarUrl || ''
          }
          this.doctorCache[id] = row
          return { ...rec, ...row }
        } catch (e) {
          // 失败不阻断
          return { ...rec }
        }
      })
      const rows = await Promise.all(tasks)
      this.rows = rows.filter(Boolean)
      // 依据当前过滤和页码更新 finished
      this.finished = this.pagedList.length >= this.filteredTotal
    },
    loadMore() {
      if (this.finished || this.loadingMore) return
      this.loadingMore = true
      setTimeout(() => {
        this.page += 1
        this.finished = this.pagedList.length >= this.filteredTotal
        this.loadingMore = false
      }, 0)
    },
    onSearchInput() {
      // 搜索时重置分页
      this.page = 1
      this.finished = this.pagedList.length >= this.filteredTotal
    },
    goDoctorDetail(doctorId) {
      if (!doctorId) return
      const isFollowed = this.rows.some(r => Number(r.doctorId) === Number(doctorId))
      const url = `/pages/doctors/detail.vue?doctorId=${doctorId}&isFollowed=${isFollowed ? '1' : '0'}`.replace('.vue','')
      uni.navigateTo({ url })
    },
    formatTime(ts) {
      if (!ts) return '-'
      try {
        const d = new Date(ts)
        if (isNaN(d.getTime())) return ts
        const pad = n => (n < 10 ? '0' + n : '' + n)
        return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`
      } catch (_) {
        return ts
      }
    },
    async onCancel(item) {
      try {
        if (this._cancelBusy) return
        this._cancelBusy = true
        try { console.log('[Follow] onCancel item=', item) } catch (_) {}
        let doctorId = null
        if (item) {
          const cand = item.doctorId ?? item.doctor_id ?? item.docId ?? item.doc_id ?? item.doctorID ?? item.id
          if (cand !== undefined && cand !== null) {
            try { doctorId = Number(String(cand).trim()) } catch (_) { doctorId = Number(cand) }
          }
        }
        console.log('[Follow] onCancel start, doctorId=', doctorId)
        if (!doctorId) {
          uni.showToast({ title: '数据异常，缺少医生ID', icon: 'none' })
          this._cancelBusy = false
          return
        }
        uni.showLoading({ title: '处理中' })
        const res = await cancelFollow(doctorId)
        console.log('[Follow] cancelFollow response:', res)
        uni.showToast({ title: '已取消', icon: 'none' })
        // 从数据中移除并更新分页
        this.rawList = this.rawList.filter(r => Number(r.doctorId) !== Number(doctorId))
        this.rows = this.rows.filter(r => Number(r.doctorId) !== Number(doctorId))
        this.page = 1
        this.finished = this.pagedList.length >= this.filteredTotal
      } catch (e) {
        console.error('[Follow] 取消关注失败', e)
        uni.showToast({ title: '取消失败', icon: 'none' })
      } finally {
        uni.hideLoading()
        this._cancelBusy = false
      }
    }
    ,
    async onCancelById(eOrId, idx) {
      try {
        let did = eOrId
        if (typeof eOrId === 'object' && eOrId && eOrId.currentTarget) {
          const ds = eOrId.currentTarget.dataset || {}
          did = ds.id ?? ds.doctorId ?? ds.doctorid
          idx = ds.idx != null ? Number(ds.idx) : idx
        }
        const idNum = did != null ? Number(String(did).trim()) : null
        console.log('[Follow] onCancelById param: idx=', idx, ' id=', did, ' -> ', idNum)
        if (!idNum) {
          const fallback = (idx != null && this.pagedList && this.pagedList[idx])
            || (this.pagedList?.find(r => Number(r.doctorId) === Number(did)))
            || {}
          return this.onCancel(fallback)
        }
        return this.onCancel({ doctorId: idNum })
      } catch (err) {
        console.warn('onCancelById error', err)
        return this.onCancel({})
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.follow-container { min-height: 100vh; background: #f5f5f5; }
.nav { padding: 24rpx 30rpx; background: #fff; border-bottom: 1rpx solid #f0f0f0; }
.title { font-size: 32rpx; font-weight: 600; color: #333; }
.toolbar { padding: 16rpx 30rpx; background: #fff; border-bottom: 1rpx solid #f5f5f5; }
.search { width: 100%; background: #f7f8fa; border-radius: 28rpx; padding: 18rpx 24rpx; font-size: 26rpx; }
.loading, .empty { padding: 60rpx 30rpx; color: #999; text-align: center; }
.list { margin-top: 20rpx; }
.item { display: flex; align-items: center; gap: 20rpx; padding: 24rpx 30rpx; background: #fff; border-bottom: 1rpx solid #f0f0f0; }
.avatar { width: 100rpx; height: 100rpx; border-radius: 50rpx; background: #eee; flex-shrink: 0; }
.info { flex: 1; min-width: 0; }
.line1 { display: flex; align-items: center; gap: 12rpx; }
.name { font-size: 30rpx; color: #333; font-weight: 600; max-width: 420rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.title-badge { font-size: 22rpx; color: #667eea; background: #eef2ff; padding: 6rpx 12rpx; border-radius: 8rpx; }
.line2 { font-size: 24rpx; color: #666; margin-top: 6rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.time { display: block; margin-top: 6rpx; font-size: 22rpx; color: #999; }
.ops { flex-shrink: 0; }
.btn-cancel { background: #fff; color: #ff4d4f; border: 1rpx solid #ff4d4f; }
.load-more, .no-more { padding: 20rpx 0; text-align: center; color: #999; }
.btn-more { background: #fff; border: 1rpx solid #ddd; color: #333; }
</style>
